{
 "cells": [
  {
   "cell_type": "raw",
   "id": "25bd9564",
   "metadata": {
    "raw_mimetype": "text/restructuredtext"
   },
   "source": [
    ".. _quick-start:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4746904c",
   "metadata": {},
   "source": [
    "# What is Featuretools?\n",
    "<img src=\"_static/images/featuretools_nav2.svg\" width=\"500\" align=\"center\" alt=\"Featuretools\">\n",
    "\n",
    "\n",
    "**Featuretools** is a framework to perform automated feature engineering. It excels at transforming temporal and relational datasets into feature matrices for machine learning.\n",
    "\n",
    "\n",
    "## 5 Minute Quick Start\n",
    "\n",
    "Below is an example of using Deep Feature Synthesis (DFS) to perform automated feature engineering. In this example, we apply DFS to a multi-table dataset consisting of timestamped customer transactions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2ed1924f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import featuretools as ft"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3bc51d89",
   "metadata": {},
   "source": [
    "#### Load Mock Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "be39a49a",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = ft.demo.load_mock_customer()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eb2552f2",
   "metadata": {},
   "source": [
    "#### Prepare data\n",
    "\n",
    "In this toy dataset, there are 3 DataFrames.\n",
    "\n",
    "- **customers**: unique customers who had sessions\n",
    "- **sessions**: unique sessions and associated attributes\n",
    "- **transactions**: list of events in this session\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9bb55d86",
   "metadata": {},
   "outputs": [],
   "source": [
    "customers_df = data[\"customers\"]\n",
    "customers_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2054eb2a",
   "metadata": {},
   "outputs": [],
   "source": [
    "sessions_df = data[\"sessions\"]\n",
    "sessions_df.sample(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "348e7614",
   "metadata": {},
   "outputs": [],
   "source": [
    "transactions_df = data[\"transactions\"]\n",
    "transactions_df.sample(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "59fc2126",
   "metadata": {},
   "source": [
    "First, we specify a dictionary with all the DataFrames in our dataset. The DataFrames are passed in with their index column and time index column if one exists for the DataFrame."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b3fdc96a",
   "metadata": {},
   "outputs": [],
   "source": [
    "dataframes = {\n",
    "    \"customers\": (customers_df, \"customer_id\"),\n",
    "    \"sessions\": (sessions_df, \"session_id\", \"session_start\"),\n",
    "    \"transactions\": (transactions_df, \"transaction_id\", \"transaction_time\"),\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0d84890",
   "metadata": {},
   "source": [
    "Second, we specify how the DataFrames are related. When two DataFrames have a one-to-many relationship, we call the \"one\" DataFrame, the \"parent DataFrame\". A relationship between a parent and child is defined like this:\n",
    "    \n",
    "    (parent_dataframe, parent_column, child_dataframe, child_column)\n",
    "\n",
    "In this dataset we have two relationships"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fc4366dc",
   "metadata": {},
   "outputs": [],
   "source": [
    "relationships = [\n",
    "    (\"sessions\", \"session_id\", \"transactions\", \"session_id\"),\n",
    "    (\"customers\", \"customer_id\", \"sessions\", \"customer_id\"),\n",
    "]"
   ]
  },
  {
   "cell_type": "raw",
   "id": "758f8fd4",
   "metadata": {
    "raw_mimetype": "text/restructuredtext"
   },
   "source": [
    ".. note::\n",
    "\n",
    "    To manage setting up DataFrames and relationships, we recommend using the :class:`EntitySet <featuretools.EntitySet>` class which offers convenient APIs for managing data like this. See :doc:`getting_started/using_entitysets` for more information."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "330d66b0",
   "metadata": {},
   "source": [
    "#### Run Deep Feature Synthesis\n",
    "\n",
    "A minimal input to DFS is a dictionary of DataFrames, a list of relationships, and the name of the target DataFrame whose features we want to calculate. The ouput of DFS is a feature matrix and the corresponding list of feature definitions.\n",
    "\n",
    "Let's first create a feature matrix for each customer in the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "13cae382",
   "metadata": {},
   "outputs": [],
   "source": [
    "feature_matrix_customers, features_defs = ft.dfs(\n",
    "    dataframes=dataframes,\n",
    "    relationships=relationships,\n",
    "    target_dataframe_name=\"customers\",\n",
    ")\n",
    "feature_matrix_customers"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71628a1c",
   "metadata": {},
   "source": [
    "We now have dozens of new features to describe a customer's behavior.\n",
    "\n",
    "#### Change target DataFrame\n",
    "One of the reasons DFS is so powerful is that it can create a feature matrix for *any* DataFrame in our EntitySet. For example, if we wanted to build features for sessions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4cfe1aca",
   "metadata": {
    "nbsphinx": "hidden"
   },
   "outputs": [],
   "source": [
    "dataframes = {\n",
    "    \"customers\": (customers_df.copy(), \"customer_id\"),\n",
    "    \"sessions\": (sessions_df.copy(), \"session_id\", \"session_start\"),\n",
    "    \"transactions\": (transactions_df.copy(), \"transaction_id\", \"transaction_time\"),\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "84fec203",
   "metadata": {},
   "outputs": [],
   "source": [
    "feature_matrix_sessions, features_defs = ft.dfs(\n",
    "    dataframes=dataframes, relationships=relationships, target_dataframe_name=\"sessions\"\n",
    ")\n",
    "feature_matrix_sessions.head(5)"
   ]
  },
  {
   "cell_type": "raw",
   "id": "a67d574e",
   "metadata": {
    "raw_mimetype": "text/restructuredtext"
   },
   "source": [
    "Understanding Feature Output\n",
    "~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "\n",
    "In general, Featuretools references generated features through the feature name. In order to make features easier to understand, Featuretools offers two additional tools, :func:`featuretools.graph_feature` and :func:`featuretools.describe_feature`, to help explain what a feature is and the steps Featuretools took to generate it. Let's look at this example feature:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9c791dda",
   "metadata": {},
   "outputs": [],
   "source": [
    "feature = features_defs[18]\n",
    "feature"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84b5be0f",
   "metadata": {},
   "source": [
    "##### Feature lineage graphs\n",
    "\n",
    "Feature lineage graphs visually walk through feature generation. Starting from the base data, they show step by step the primitives applied and intermediate features generated to create the final feature."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0cd93f3d",
   "metadata": {},
   "outputs": [],
   "source": [
    "ft.graph_feature(feature)"
   ]
  },
  {
   "cell_type": "raw",
   "id": "d6e5e0a1",
   "metadata": {
    "raw_mimetype": "text/restructuredtext"
   },
   "source": [
    ".. graphviz:: getting_started/graphs/demo_feat.dot\n",
    "\n",
    "Feature descriptions\n",
    "\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n",
    "\n",
    "Featuretools can also automatically generate English sentence descriptions of features. Feature descriptions help to explain what a feature is, and can be further improved by including manually defined custom definitions. See :doc:`/guides/feature_descriptions` for more details on how to customize automatically generated feature descriptions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3bdbe1c0",
   "metadata": {},
   "outputs": [],
   "source": [
    "ft.describe_feature(feature)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "44635e1f",
   "metadata": {},
   "source": [
    "## What's next?\n",
    "\n",
    "\n",
    "* Learn about [Representing Data with EntitySets](getting_started/using_entitysets.ipynb)\n",
    "* Apply automated feature engineering with [Deep Feature Synthesis](getting_started/afe.ipynb)\n",
    "* Explore [runnable demos](https://www.featuretools.com/demos) based on real world use cases\n",
    "* Can't find what you're looking for? Ask for [help](resources/help.rst)"
   ]
  },
  {
   "cell_type": "raw",
   "id": "cb2d443c",
   "metadata": {
    "raw_mimetype": "text/restructuredtext"
   },
   "source": [
    "Table of contents\n",
    "-----------------\n",
    "\n",
    ".. toctree::\n",
    "   :maxdepth: 1\n",
    "\n",
    "   install\n",
    "\n",
    ".. toctree::\n",
    "   :maxdepth: 2\n",
    "\n",
    "   getting_started/getting_started_index\n",
    "   guides/guides_index\n",
    "\n",
    ".. toctree::\n",
    "   :maxdepth: 1\n",
    "   :caption: Resources and References\n",
    "\n",
    "   resources/resources_index\n",
    "   api_reference\n",
    "   release_notes\n",
    "\n",
    "Other links\n",
    "------------\n",
    "* :ref:`genindex`\n",
    "* :ref:`search`\n"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Raw Cell Format",
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
